package org.example.pinda.database.datasource;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.parser.ISqlParser;
import com.baomidou.mybatisplus.extension.parsers.BlockAttackSqlParser;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import lombok.AllArgsConstructor;
import org.apache.ibatis.reflection.MetaObject;
import org.example.pinda.base.id.IdGenerator;
import org.example.pinda.base.id.SnowflakeIdGenerate;
import org.example.pinda.database.mybatis.typehandler.FullLikeTypeHandler;
import org.example.pinda.database.mybatis.typehandler.LeftLikeTypeHandler;
import org.example.pinda.database.mybatis.typehandler.RightLikeTypeHandler;
import org.example.pinda.database.properties.DatabaseProperties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;

import java.util.ArrayList;
import java.util.List;

/**
 * MyBatis基础抽象配置
 *
 * @author ryan fawcett
 */
@AllArgsConstructor
public abstract class BaseMybatisConfiguration {

    private final DatabaseProperties databaseProperties;

    /**
     * 分页插件，自动识别数据库
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        List<ISqlParser> sqlParserList = new ArrayList<>();
        // 攻击SQL阻断解析器，加入解析链
        if (this.databaseProperties.getIsBlockAttack()) {
            sqlParserList.add(new BlockAttackSqlParser());
        }
        paginationInterceptor.setSqlParserList(sqlParserList);
        return paginationInterceptor;
    }

    /**
     * Mybatis Plus 注入器
     */
    @Bean
    public MetaObjectHandler metaObjectHandler(IdGenerator<Long> idGenerator) {
        return new MyMetaObjectHandler(idGenerator);
    }

    /**
     * id生成机器码，单机配置1即可。集群部署，每个实例自增1即可。
     */
    @Bean("snowflakeIdGenerate")
    public IdGenerator<Long> getIdGenerate(@Value("${id-generator.machine-code:1}") Long machineCode) {
        return new SnowflakeIdGenerate(machineCode);
    }

    /**
     * Mybatis 自定义的类型处理器
     * 用于左模糊查询时使用
     * <p>
     * eg：
     * and name like #{name,typeHandler=leftLike}
     *
     * @return {@link LeftLikeTypeHandler}
     */
    @Bean
    public LeftLikeTypeHandler getLeftLikeTypeHandler() {
        return new LeftLikeTypeHandler();
    }

    /**
     * Mybatis 自定义的类型处理器
     * 用于右模糊查询时使用
     * <p>
     * eg：
     * and name like #{name,typeHandler=rightLike}
     *
     * @return {@link RightLikeTypeHandler}
     */
    @Bean
    public RightLikeTypeHandler getRightLikeTypeHandler() {
        return new RightLikeTypeHandler();
    }

    /**
     * Mybatis 自定义的类型处理器
     * 用于全模糊查询时使用
     * <p>
     * eg：
     * and name like #{name,typeHandler=fullLike}
     *
     * @return {@link FullLikeTypeHandler}
     */
    @Bean
    public FullLikeTypeHandler getFullLikeTypeHandler() {
        return new FullLikeTypeHandler();
    }

}
